package com.iot08.admin.service;

import com.aliyuncs.utils.StringUtils;
import com.iot08.admin.service.page.PageVO;
import com.iot08.admin.service.page.PageableImpl;
import com.iot08.common.entity.admin.SysUser;
import com.iot08.common.entity.app.Channels;
import com.iot08.common.entity.app.VersionUpdates;
import com.iot08.common.response.Response;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.RandomUtil;
import com.iot08.common.utils.StringUtil;
import com.mongodb.client.FindIterable;
import com.mongodb.client.model.Filters;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @version 1.0
 * @Description:
 * @time: 2020/10/23 16:47
 * @author: Rock
 */
@Slf4j
@Service
public class VersionUpdatesService {

    @Resource(name = "appMongoTemplate")
    private MongoTemplate mongoTemplate;

    @Resource
    private OperationService operationService;
    @Resource
    private AppChannelService appChannelService;

    /**
     * @param page
     * @param user
     * @time: 2020/10/23 17:00
     * @author: Rock
     * @version 1.0
     */
    public Page<VersionUpdates> list(PageVO page, SysUser user) {
        PageableImpl pageable = new PageableImpl();
        page.setSort(Sort.by(Sort.Order.desc("createtime")));
        pageable.setPage(page);
        Criteria criteria = new Criteria();
        Query query = new Query().addCriteria(criteria);
        long count = mongoTemplate.count(query, VersionUpdates.class);
        page.setTotalResult((int) count);
        List<VersionUpdates> list = mongoTemplate.find(query.with(pageable), VersionUpdates.class);
        Page<VersionUpdates> result = new PageImpl<VersionUpdates>(list, pageable, count);
        return result;
    }

    /**
     * @param id
     * @time: 2020/10/23 18:18
     * @author: Rock
     * @version 1.0
     */
    public VersionUpdates getById(String id) {
        if (ObjectId.isValid(id)) {
            return mongoTemplate.findOne(new Query(Criteria.where("_id").is(new ObjectId(id))), VersionUpdates.class);
        }
        return null;
    }

    /**
     * @param channel
     * @time: 2020/10/23 18:15
     * @author: Rock
     * @version 1.0
     */
    public void add(HttpServletRequest request, SysUser user, String ip) {
        Document vu = new Document();
        vu.append("remark", request.getParameter("remark"));
        vu.append("status", 0);
        vu.append("creater", user.getAccount());
        Date date = new Date();
        DateUtil.hanldeMongoDate(date, 1);
        vu.append("createtime", date);
        List<Channels> list = appChannelService.listAll();
        for (Channels channel : list) {
            String key = channel.getShortName();
            String url  = request.getParameter(key + "_url");
            url = StringUtils.isEmpty(url)?url:url.replace(" ","");
            String iosUrl =  request.getParameter(key + "_ios_url");
            iosUrl = StringUtils.isEmpty(iosUrl)?iosUrl:iosUrl.replace(" ","");
            Update update = new Update();
            Document doc = new Document();
            update.set("version", request.getParameter(key + "_version"));
            doc.append("version", request.getParameter(key + "_version"));
            update.set("version_code", request.getParameter(key + "_version_code"));
            doc.append("version_code", request.getParameter(key + "_version_code"));
            update.set("url", url);
            doc.append("url", url);
            update.set("ios_url",iosUrl);
            doc.append("ios_url", iosUrl);
            update.set("ios_version", request.getParameter(key + "_ios_version"));
            doc.append("ios_version", request.getParameter(key + "_ios_version"));
            update.set("ios_content", request.getParameter(key + "_ios_content"));
            doc.append("ios_content", request.getParameter(key + "_ios_content"));
            String androidContent = request.getParameter(key + "_android_content");
            update.set("android_content", androidContent);
            doc.append("android_content", androidContent);
            update.set("update_description", androidContent);
            doc.append("update_description", androidContent);
            vu.append(key, doc);
            Query query = new Query(Criteria.where("short_name").is(key));
            mongoTemplate.updateFirst(query, update, "channels");
        }
        String updateid = RandomUtil.getRandomStr(6);
        vu.append("updateid", updateid);
        mongoTemplate.getCollection("version_updates").insertOne(vu);
        operationService.add(user, ip, null, "版本更新", null, "添加",
                String.format("添加运营版本更新: %s ", updateid), null, null, null);
    }

    /**
     * @param channel
     * @param user
     * @param ip
     * @time: 2020/10/23 18:28
     * @author: Rock
     * @version 1.0
     */
    public void update(HttpServletRequest request, SysUser user, String ip) {
        Update vu = new Update();
        vu.set("remark", request.getParameter("remark"));
        vu.set("modifytime", new Date());
        List<Channels> list = appChannelService.listAll();
        for (Channels channel : list) {
            String key = channel.getShortName();
            Document doc = new Document();
            String url  = request.getParameter(key + "_url");
            url = StringUtils.isEmpty(url)?url:url.replace(" ","");
            String iosUrl =  request.getParameter(key + "_ios_url");
            iosUrl = StringUtils.isEmpty(iosUrl)?iosUrl:iosUrl.replace(" ","");
            doc.append("version", request.getParameter(key + "_version"));
            doc.append("version_code", request.getParameter(key + "_version_code"));
            doc.append("url", url);
            doc.append("ios_url",iosUrl);
            doc.append("ios_version", request.getParameter(key + "_ios_version"));
            doc.append("ios_content", request.getParameter(key + "_ios_content"));
            String androidContent = request.getParameter(key + "_android_content");
            doc.append("android_content", androidContent);
            doc.append("update_description", androidContent);
            vu.set(key, doc);
        }
        Query query = new Query(Criteria.where("_id").is(new ObjectId(request.getParameter("id"))));
        mongoTemplate.updateFirst(query, vu, "version_updates");
        VersionUpdates versionUpdates = getById(request.getParameter("id"));
        operationService.add(user, ip, null, "版本更新", null, "编辑",
                String.format("修改运营版本更新: %s ", versionUpdates.getUpdateid()), null, null, null);
    }

    /**
     * @param id
     * @time: 2020/11/28 14:30
     * @author: Rock
     * @version 1.0
     */
    public Map<String, Object> show(String id) {
        Map<String, Object> map = new HashMap<>();
        List<Document> list = new ArrayList<>();
        Bson bson = Filters.eq("_id", new ObjectId(id));
        FindIterable<Document> document = mongoTemplate.getCollection("version_updates").find(bson);
        for (Document d : document) {
            for (String key : d.keySet()) {
                Object value = d.get(key);
                if (value instanceof Document) {
                    Channels channel = appChannelService.getByShortName(key);
                    if (channel != null) {
                        ((Document) value).append("name", channel.getName());
                    }
                    list.add((Document) value);
                }
                if ("remark".equals(key)) {
                    map.put("remark", value);
                }
            }
        }
        map.put("versions", list);
        return map;
    }

    /**
     * @time: 2020/10/27 10:04
     * @author: Rock
     * @version 1.0
     */
    public Map<String, Object> getAdd() {
        Map<String, Object> map = new HashMap<>();
        List<Document> list = new ArrayList<>();
        List<Channels> channels = appChannelService.listAll();
        for (Channels channel : channels) {
            if (channel != null) {
                String key = channel.getShortName();
                Document doc = new Document();
                doc.append("name", channel.getName());
                doc.append("version", new Document().append("name", key + "_version").append("value", channel.getVersion()));
                doc.append("url", new Document().append("name", key + "_url").append("value", channel.getUrl()));
                doc.append("ios_url", new Document().append("name", key + "_ios_url").append("value", channel.getIosUrl()));
                doc.append("ios_version", new Document().append("name", key + "_ios_version").append("value", channel.getIosVersion()));
                doc.append("update_description", new Document().append("name", key + "_update_description").append("value", channel.getUpdateDescription()));
                doc.append("android_content", new Document().append("name", key + "_android_content").append("value", channel.getAndroidContent()));
                doc.append("ios_content", new Document().append("name", key + "_ios_content").append("value", channel.getAndroidContent()));
                doc.append("version_code", new Document().append("name", key + "_version_code").append("value", channel.getVersionCode()));
                list.add(doc);
            }
        }
        map.put("versions", list);
        return map;
    }

    /**
     * @param id
     * @time: 2020/10/27 10:03
     * @author: Rock
     * @version 1.0
     */
    public Map<String, Object> getEdit(String id) {
        Map<String, Object> map = new HashMap<>();
        List<Document> list = new ArrayList<>();
        Bson bson = Filters.eq("_id", new ObjectId(id));
        FindIterable<Document> documents = mongoTemplate.getCollection("version_updates").find(bson);
        for (Document document : documents) {
            for (String key : document.keySet()) {
                Object value = document.get(key);
                if (value instanceof Document) {
                    Document d = (Document) value;
                    Document doc = new Document();
                    Channels channel = appChannelService.getByShortName(key);
                    if (channel != null) {
                        doc.append("name", channel.getName());
                    }
                    doc.append("version", new Document().append("name", key + "_version").append("value", d.getString("version")));
                    doc.append("url", new Document().append("name", key + "_url").append("value", d.getString("url")));
                    doc.append("ios_url", new Document().append("name", key + "_ios_url").append("value", d.getString("ios_url")));
                    doc.append("ios_version", new Document().append("name", key + "_ios_version").append("value", d.getString("ios_version")));
                    doc.append("update_description", new Document().append("name", key + "_update_description").append("value", d.getString("update_description")));
                    doc.append("android_content", new Document().append("name", key + "_android_content").append("value", d.getString("android_content")));
                    doc.append("ios_content", new Document().append("name", key + "_ios_content").append("value", d.getString("ios_content")));
                    doc.append("version_code", new Document().append("name", key + "_version_code").append("value", d.getString("version_code")));
                    list.add(doc);
                }
                if ("remark".equals(key)) {
                    map.put("remark", value);
                }
            }
        }
        map.put("versions", list);
        map.put("id", id);
        return map;
    }

    /**
     * @param id
     * @param user
     * @param ip
     * @time: 2020/10/26 18:31
     * @author: Rock
     * @version 1.0
     */
    public Response<Object> updateStatus(String id, SysUser user, String ip) {
        if (ObjectId.isValid(id)) {
            Bson bson = Filters.eq("_id", new ObjectId(id));
            FindIterable<Document> documents = mongoTemplate.getCollection("version_updates").find(bson);
            if (documents == null || documents.first() == null) {
                return Response.failedResponse();
            }
            Document document = documents.first();
            List<Channels> list = appChannelService.listAll();
            for (Channels channel : list) {
                String key = channel.getShortName();
                if (!document.containsKey(key) || document.get(key) instanceof Document == false) {
                    continue;
                }
                Update update = new Update();
                Document doc = (Document) document.get(key);
                update.set("version", doc.get("version"));
                update.set("version_code", doc.get("version_code"));
                update.set("url", doc.get("url"));
                update.set("ios_url", doc.get("ios_url"));
                update.set("ios_version", doc.get("ios_version"));
                update.set("ios_content", doc.get("ios_content"));
                String androidContent = doc.getString("android_content");
                update.set("android_content", androidContent);
                update.set("update_description", androidContent);
                update.set("status", 1);
                Query query = new Query(Criteria.where("short_name").is(key));
                mongoTemplate.updateFirst(query, update, "channels");
            }
            Update versionUpdate = new Update();
            versionUpdate.set("status", 1);
            versionUpdate.set("publisher", user.getAccount());
            versionUpdate.set("publishtime", new Date());
            Query query = new Query(Criteria.where("_id").is(new ObjectId(id)));
            mongoTemplate.updateFirst(query, versionUpdate, "version_updates");
            operationService.add(user, ip, null, "版本更新", null, "发布",
                    String.format("发布运营版本更新: %s ", document.getString("updateid")), null, null, null);
            return Response.successResponse();
        }
        return Response.failedResponse();
    }

    /**
     * @param id
     * @param status
     * @param user
     * @param ip
     * @time: 2020/10/26 18:43
     * @author: Rock
     * @version 1.0
     */
    public Response<Object> forceUpdateStatus(String id, Integer status, SysUser user, String ip) {
        if (ObjectId.isValid(id)) {
            Query query = new Query(Criteria.where("_id").is(new ObjectId(id)));
            VersionUpdates vu = mongoTemplate.findOne(query, VersionUpdates.class);
            if (vu != null) {
                Update update = new Update();
                update.set("forceUpdate_status", status);
                update.set("forceUpdate_user", user.getAccount());
                update.set("forceUpdate_time", new Date());
                mongoTemplate.updateFirst(query, update, VersionUpdates.class);
                operationService.add(user, ip, null, "版本更新", null, "编辑",
                        String.format("设置强制更新开关: %s ", status), null, null, null);
                return Response.successResponse();
            }
        }
        return Response.failedResponse();
    }

    /**
     * @param id
     * @param user
     * @param ip
     * @time: 2020/10/31 18:35
     * @author: Rock
     * @version 1.0
     */
    public Response<Object> del(String id, SysUser user, String ip) {
        if (ObjectId.isValid(id)) {
            Query query = new Query(Criteria.where("_id").is(new ObjectId(id)));
            VersionUpdates vu = mongoTemplate.findOne(query, VersionUpdates.class);
            if (vu != null) {
                String updateid = vu.getUpdateid();
                mongoTemplate.remove(query, VersionUpdates.class);
                operationService.add(user, ip, null, "版本更新", null, "删除",
                        String.format("删除运营版本更新: %s ", updateid), null, null, null);
                return Response.successResponse();
            }
        }
        return Response.failedResponse();
    }

    /**
     * 判断字段是否存在
     *
     * @param field
     * @time: 2020/11/2 11:57
     * @author: Rock
     * @version 1.0
     */
    public boolean existField(String field) {
        Query query = new Query(Criteria.where(field).exists(true));
        return mongoTemplate.count(query, VersionUpdates.class) > 0;
    }
}
